package loan.calc.calculator.instalment.impl;

import loan.calc.calculator.instalment.InstalmentCalculatorParamDTO;
import loan.calc.constant.dict.RepayMethodDictEnum;
import loan.calc.util.BigDecimalUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 等额本金期供计算器
 * 在还款期内把贷款数总额等分，每月偿还同等数额的本金和剩余贷款在该月所产生的利息
 *
 * @author v_ECD963
 */
@Component
public class PrincipalEqualCalculatorImpl extends AbstractInstalmentCalculator{

    @Override
    public RepayMethodDictEnum support() {
        return RepayMethodDictEnum.EQ_P;
    }

    /**
     * 等额本金的期供为期供本金
     *
     * @param param
     * @return 期供金额 保留两位小数
     */
    @Override
    public BigDecimal calcInstalmentAmount(InstalmentCalculatorParamDTO param) {
        return calcInstalmentPrincipal(param);
    }

    /**
     * 计算本金
     * @param param
     * @return
     */
    @Override
    public BigDecimal calcInstalmentPrincipal(InstalmentCalculatorParamDTO param) {
        if (param.getOutstandingPeriods() == 0) {
            //特殊情况，如果剩余期数为0，则期供为0。应该不会出现，因为正常rpt，最少剩余期数也为1
            return BigDecimal.ZERO;
        }
        // 等额本金一个区段内的每个期次的应还本金也会有细微差距（期次往后走了，剩余本金和剩余期数都会变化，因为每次计算期供本金都是剩余金额除以剩余期数，所以各个期次之间会有细微差异）
        BigDecimal instalmentPrincipalAmt = param.getPrincipalBalance().divide(BigDecimal.valueOf(param.getOutstandingPeriods()), BigDecimalUtils.CALCULATING_CURRENCY_SCALE, BigDecimalUtils.DEFAULT_CURRENCY_ROUNDING_MODE);
        return BigDecimalUtils.roundCurrency(instalmentPrincipalAmt);
    }

    /**
     * 计算利息
     * @param param
     * @return
     */
    @Override
    public BigDecimal calcInstalmentInterest(InstalmentCalculatorParamDTO param) {
        BigDecimal ret = param.getPrincipalBalance().multiply(param.getPeriodRate());
        ret = BigDecimalUtils.roundCurrency(ret);
        param.setInterestAmt(ret);
        return ret;
    }
}
